/***********************************************************************************
Copy right:     2020-2030 ESP8266 AP demo.
Author:         hujianguo
Date:           2022.7.22
Description:    终端STA服务处理程序
***********************************************************************************/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Servo.h>//舵机不简单哦，去看一看自己的IDE是否有Servo的库哈！

Servo myservo;  // 定义舵机对象，myservo就是这次要用的舵机名称后续会用到 

/**************** WIFI及默认配置 *****************/
const char *APssid = "apapapap";             //AP的SSID（WiFi名字）
const char *APpassword = "12345678";            //AP的密码
int Relay = 0;                                 //设置继电器控制IO（这里为dio0）

/**************** UDP设置项 *****************/
unsigned int read_Port = 11234;     //监听端口
unsigned int send_Port = 11235;     //发送端口
char readdata[512];                 //数据缓存
WiFiUDP Udp;                        //定义udp
IPAddress ap_ip(192, 168, 2, 1);        //AP的ip地址

static String OpenString = "openc_success";
static String CloseString = "closec_success";
static String ErrorString = "error";
/****************io设置项 *****************/

//初始化io
void init_IO()
{
  pinMode(Relay, OUTPUT);//设置指定io为输出模式
  //digitalWrite(Relay, 0);//初始化为低电平，断开继电器，关闭灯状态（板载led和继电器并联，状体一致）     
}

//初始化AP信息
void init_STA()
{
  IPAddress local_ip(192, 168, 2, 4);
  IPAddress arg1(192, 168, 2, 1);
  IPAddress arg2(255, 255, 255, 0);
  IPAddress arg3(192, 168, 2, 1);
  IPAddress dns2(192, 168, 2, 1);
  WiFi.disconnect();
  WiFi.config(local_ip, arg1, arg2, arg3, dns2);
  WiFi.mode(WIFI_STA);
  WiFi.begin(APssid, APpassword);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  
  //几句提示
  Serial.println("WiFi Connect success.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

/*自定义函数
  将接收的数据，以String类型返回，方便分析处理
*/
String Read_Udp() 
{
  String data = "";
  int packetSize = Udp.parsePacket();
  if (packetSize) 
  {
    memset(readdata, 0x00, sizeof(readdata));
    Udp.read(readdata, 511);
    Udp.flush();
    for (int i = 0; i < packetSize; i++) 
    {
      data += readdata[i];
    }
    Serial.println(data);
  }
  return data;
}

/************自定义函数，对接收数据分析处理************/
void Udp_Handler(String data) {
  if (data != "") 
  {
    Serial.printf("Udp_Handler data = %s \r\n", data);
    if (data == "open_c\n") 
    {
      digitalWrite(Relay, HIGH);
      myservo.write(180);  //写入舵机应该到达的位置。
      Serial.println(data);
//      Serial.println("open success\r\n");
      Udp.beginPacket(ap_ip, send_Port);
      Udp.print(OpenString);
      Udp.endPacket();
    }
    else if (data == "close_c\n") 
    {
      digitalWrite(Relay, LOW);
      myservo.write(0);  //写入舵机应该到达的位置。
      Serial.println(data);
//      Serial.println("close success\r\n");
      Udp.beginPacket(ap_ip, send_Port);
      Udp.print(CloseString);
      Udp.endPacket();
    }
  }
}

void setup() 
{
  Serial.begin(115200);
  Serial.println("");
  Serial.printf("***** 串口初始化完成 *****\r\n");
  init_IO(); //初始化需要的IO引脚
  init_STA();
  Udp.begin(read_Port);             //UDP设置监听指定端口

  myservo.attach(Relay);  // 设置舵机控制针脚：1
}

void loop()
{
   Udp_Handler(Read_Udp());
}
